home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1994 November / macformat-018.iso / Utility Spectacular / Developer / macgzip_022-src / macos / Posix / ThinkCPosix Sources / GetPref.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-26  |  5.9 KB  |  247 lines  |  [TEXT/MPS ]

  1. /*
  2.  * Athough getenv() is nominally implemented in Think-C,
  3.  * it simply returns NULL.
  4.  * This proposed Think-C replacement for getenv()
  5.  * searches a specified file in the Preference Folder --
  6.  * as found by the in-built function FindFolder() --
  7.  * and reads through it for the definition of an "environment variable".
  8.  *
  9.  * More precisely, the replacement function getpref(char *env_name)
  10.  * looks in the Preference folder
  11.  * for the file with the externally-defined PreferenceName.
  12.  * If there is a line in this file of the form
  13.  * ENVNAME = "env_value";
  14.  * then getpref("ENVNAME") returns "env_value".
  15.  *
  16.  * The intention is that getenv() be over-ridden by getpref()
  17.  * through a judiciously placed
  18.  *
  19.  * #define getenv(env_name) getpref(env_name)
  20.  *
  21.  * This source is largely copied from a file Preference.c,
  22.  * the name of whose author I have unfortunately mislaid.
  23.  * 
  24.  * Timothy Murphy <tim@maths.tcd.ie>
  25.  */
  26.  
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <string.h>
  30. #include <errno.h>
  31. #include <unix.h>
  32. #include <ctype.h>
  33. #include <Traps.h>
  34. #include <GestaltEqu.h>
  35. #include <Folders.h>
  36. extern int errno;
  37.  
  38. extern char *PreferenceName;
  39. char PreferencePath[FILENAME_MAX] = "";
  40.  
  41. #define ENVIRONMENT_SIZE 4096
  42. #define MAX_ENV 32
  43.  
  44. static char *Environment;
  45. static char *Env_name[MAX_ENV];
  46.  
  47. /* Defines for GestaltAvailable */
  48. #define GESTALT_TRAP                0xA1AD
  49.  
  50. /* Defines for FindPrefFolder */
  51. #define BTstQ(arg, bitnbr)            (arg & (1 << bitnbr))
  52.  
  53. /* Prototypes */
  54. char*        getpref(char*);
  55. FILE*        OpenPreferenceFile(char*);
  56. int            GetPathName(char*, short, long);
  57. int            GestaltAvailable(void);
  58. OSErr        FindPrefFolder(short *, long *);
  59. Boolean        TrapAvailable(int);
  60. TrapType    GetTrapType (int);
  61. int            NumToolboxTraps(void);
  62.  
  63. char *getpref(char *env_name)
  64. {
  65.     short VRefNum;
  66.     long DirID;
  67.     FILE *fp;
  68.     char line[256];
  69.     char *Environment, *Env_end, *cp;
  70.     int i = 0;
  71.     static int read_already = 0;
  72.     
  73.     if (read_already++ == 0) {
  74.         if ((Environment = malloc(ENVIRONMENT_SIZE)) == NULL)
  75.             return NULL;
  76.         Env_end = Environment + ENVIRONMENT_SIZE;
  77.         if (FindPrefFolder(&VRefNum, &DirID) == noErr)
  78.             GetPathName(PreferencePath, VRefNum, DirID);
  79.         else
  80.             return NULL;
  81.         strcat(PreferencePath, ":");
  82.         strcat(PreferencePath, PreferenceName);
  83.         fp = fopen(PreferencePath, "r");
  84.         if (fp == NULL) {
  85.             fprintf(stderr, "\nWarning! \"%s\" not found\n", PreferencePath);
  86.             return NULL;
  87.         }
  88.         
  89.         while (fgets(line, 255, fp)) {
  90.             if (!isalnum(*line) || (cp = strchr(line, '=')) == NULL)
  91.                 continue;    /* line not of required form "ABC... = " */
  92.             (void)strtok(line, "= \t");
  93.             while (*++cp && isspace(*cp));
  94.             if (*cp == '"')
  95.                 (void)strtok(++cp, "\"");
  96.             else if (*cp)
  97.                 (void)strtok(cp, " \t\n");
  98.             if (Environment + strlen(line) + strlen(cp) + 4 >= Env_end) {
  99.                 fprintf(stderr, "Preference file too long!\n");
  100.                 break;
  101.             }
  102.             Env_name[i++] = Environment;
  103.             strcpy(Environment, line);
  104.             Environment += strlen(line) + 1;
  105.             strcpy(Environment, cp);
  106.             Environment += strlen(cp) + 1;
  107.         }
  108.         fclose(fp);
  109.     }
  110.  
  111.     for(i = 0; Env_name[i]; i++)
  112.         if (strcmp(env_name, Env_name[i]) == 0)
  113.             return (Env_name[i] + strlen(env_name) + 1);
  114.     return NULL;
  115. }
  116.  
  117. /*
  118. FindPrefFolder returns the (real) vRefNum, and the DirID of
  119. the current preference folder on System 7 and beyond. Returns
  120. info about the system folder in previous releases. It uses the
  121. Folder Manager if present, otherwise it falls back to
  122. SysEnvirons. It returns zero on success, otherwise a standard
  123. system error.
  124. */
  125.  
  126. OSErr    FindPrefFolder(foundVRefNum, foundDirID)
  127. short            *foundVRefNum;
  128. long            *foundDirID;
  129. {
  130.  
  131. long            gesResponse;
  132. SysEnvRec        envRec;
  133. WDPBRec            myWDPB;
  134. unsigned char    volName[34];
  135. OSErr            err;
  136. int                done;
  137.     
  138.     
  139. *foundVRefNum = 0;
  140. *foundDirID = 0;
  141.  
  142. done=FALSE;
  143. if(GestaltAvailable())
  144.     /* Does Folder Manager exist? */
  145.     if (!Gestalt (gestaltFindFolderAttr, &gesResponse) &&
  146.         BTstQ (gesResponse, gestaltFindFolderPresent))
  147.         {
  148.         err = FindFolder (kOnSystemDisk, kPreferencesFolderType,kDontCreateFolder,
  149.             foundVRefNum, foundDirID);
  150.         done=TRUE;
  151.         }
  152.  
  153. if(!done)    /* Gestalt can't give us the answer, so we resort to SysEnvirons */
  154.     {
  155.     if (!(err = SysEnvirons (curSysEnvVers, &envRec)))
  156.         {
  157.         myWDPB.ioVRefNum = envRec.sysVRefNum;
  158.         volName[0] = '\000';                    /* Zero volume name */
  159.         myWDPB.ioNamePtr = volName;
  160.         myWDPB.ioWDIndex = 0;
  161.         myWDPB.ioWDProcID = 0;
  162.         if (!(err = PBGetWDInfo (&myWDPB, 0)))
  163.             {
  164.             *foundVRefNum = myWDPB.ioWDVRefNum;
  165.             *foundDirID = myWDPB.ioWDDirID;
  166.             }
  167.         }
  168.     }
  169.     
  170. return (err);
  171. }
  172.  
  173.  
  174. int GestaltAvailable()
  175. {
  176. /* Gestalt is available from System Software V.6.0.4 */
  177. return(TrapAvailable(GESTALT_TRAP));
  178. }
  179.  
  180.  
  181. Boolean TrapAvailable (theTrap)
  182. int    theTrap;
  183. {
  184. TrapType    tType;
  185.  
  186. tType = GetTrapType(theTrap);
  187. if(tType == ToolTrap)
  188.     {
  189.     theTrap = theTrap & 0x07FF;
  190.     if(theTrap >= NumToolboxTraps())
  191.          theTrap = _Unimplemented;
  192.     }
  193. return(NGetTrapAddress(theTrap, tType) != NGetTrapAddress(_Unimplemented, ToolTrap));
  194. }
  195.  
  196. int NumToolboxTraps()
  197. {
  198. if(NGetTrapAddress(_InitGraf, ToolTrap) == NGetTrapAddress(0xAA6E, ToolTrap))
  199.       return(0x200);
  200.    else
  201.       return(0x400);
  202. }
  203.  
  204. TrapType GetTrapType (theTrap)
  205. int theTrap;
  206. {
  207. if((theTrap&0x0800) > 0)
  208.       return(ToolTrap);
  209.    else
  210.       return(OSTrap);
  211. }
  212.  
  213. int GetPathName(char *pathname, short vRefNum, long DirID)
  214. {
  215.     CInfoPBRec cipbr;
  216.     HFileInfo *fpb = (HFileInfo*)&cipbr;
  217.     DirInfo *dpb = (DirInfo*)&cipbr;
  218.     char dirname[FILENAME_MAX];
  219.     OSErr err;
  220.     int depth = 0;
  221.     int dirlen, pathlen = 0;
  222.     
  223.     *pathname = 0;
  224.     for (dpb->ioDrDirID = DirID; dpb->ioDrDirID >= 2; dpb->ioDrDirID = dpb->ioDrParID) {
  225.         dirname[0] = 0;
  226.         dpb->ioNamePtr = (unsigned char*)dirname;
  227.         dpb->ioVRefNum = vRefNum;
  228.         dpb->ioFDirIndex = -1;
  229.         if (PBGetCatInfo(&cipbr, FALSE)) {
  230.             errno = ENODEV;
  231.             return -1;
  232.         }
  233.         p2cstr(dirname);
  234.         if (depth++)
  235.             strcat(dirname, ":");
  236.         dirlen = strlen(dirname);
  237.         if (dirlen + pathlen + 1 >= FILENAME_MAX) {
  238.             errno = ERANGE;
  239.             return -1;
  240.         }
  241.         memmove(pathname + dirlen, pathname, pathlen + 1);
  242.         memcpy(pathname, dirname, dirlen);
  243.         pathlen += dirlen;
  244.     }
  245. }
  246.  
  247.